#include "dvbinner.h"

typedef void (*pPsiChangecallback)(unsigned char u8UpdateType, unsigned int ServiceHdID);


static char b_hasinit = 0;
static pDVBInitCallback dvbInitDonecb = NULL;
static pPsiChangecallback   psiChangecb   = NULL;

int DVBSetSystemTimezone (char timezone)
{
	int s32Ret;
	
	s32Ret = DVBSysDBSetTimezone(timezone);

	return s32Ret;
}

int DVBGetSystemTimezone ()
{
	int s32Timezone;
	
	DVBSysDBGetTimezone(&s32Timezone);
	if(s32Timezone>12 || s32Timezone<-12)
	{
		s32Timezone = 8;
	}
	
	return s32Timezone;
}

void DvbInitDone(int status)
{
	if(dvbInitDonecb)
		dvbInitDonecb(status);
}

void PsiChange(unsigned char u8UpdateType, dvb_service_t* ServiceHdID)
{
	if(psiChangecb)
		psiChangecb(u8UpdateType, (unsigned int)ServiceHdID);
}

int DVBDbaseInitialize()
{
	int s32Ret;
	
	s32Ret = DVBTSDBInit();
	s32Ret = DvbSiLoadData(); 
	s32Ret = LoadCurService();
	s32Ret = LoadUserInfo();
	DVBGroupSetCurGroupByID(GROUP_VIDEO);
	return s32Ret;
}

int DVBSystemInitialize(char *appFilesDir)
{
	int s32Ret;
	
	if(b_hasinit == 0)
	{
		b_hasinit = 1;
		mwPlatformInit(DvbInitDone,appFilesDir);
		s32Ret = DVBDbaseInitialize();
		mwDebug("DVBSystemInitialize() - DVBDbaseInitialize ret = %d\r\n", s32Ret);
		s32Ret=DVBEPGInit();
		mwDebug("DVBSystemInitialize() - DVBEPGInit ret = %d\r\n", s32Ret);
		s32Ret=DVBTDTInit();
		mwDebug("DVBSystemInitialize() - DVBTDTInit ret = %d\r\n", s32Ret);
		s32Ret = DvbBuilderInit(PsiChange);
		mwDebug("DVBSystemInitialize() - DvbBuilderInit ret = %d\r\n", s32Ret);
		s32Ret = DvbMonitorTunerInit();
		mwDebug("DVBSystemInitialize() - DvbMonitorTunerInit ret = %d\r\n", s32Ret);
		s32Ret = DvbPlayTaskInit();
		mwDebug("DVBSystemInitialize() - DvbPlayTaskInit ret = %d\r\n", s32Ret);
	}
	return s32Ret;
}

int DVBSystemDeinitialize()
{
	int ret = -1;
	
	mwDebug("DVBSystemDeinitialize() - entry---------\r\n");
	if(b_hasinit == 1)
	{
		b_hasinit = 0;
		mwAvStop(0);
		mwPlatformTerm();
		ret = 0;
	}
	return 0;
}

int DVBRegisterDvbInitDoneNotify(pDVBInitCallback callback)
{
	dvbInitDonecb = callback;
	return 1;
}

int DvbRegisterPSIChangeNotify(pPsiChangecallback callback)
{
	psiChangecb = callback;
	return 1;
}

int DVBRestoreFactorySetting()
{
 	DVBTSDBClear();
	DVBGroupsClear();
	DVBServicesDBClear();
	DvbSiSaveData();
	DVBSysDBDefaut();
	SaveCurService();
	DVBTunerReset();
	return 0;
}

int DvbResetServicesList()
{
	mwDebug("-----DvbResetServicesList---------\r\n");
 	DVBTSDBClear();
	DVBGroupsClear();
	DVBServicesDBClear();
	DvbSiSaveData();
	return 0;
}

dvb_time_t DVBGetSystemTime()
{
	return GetEndTime(DVBTDTGetGMTTime(), 60*30*DVBGetSystemTimezone());
}


int DVBSetSystemLanguage (char* lan)
{	
	memset(sys_lan, 0, sizeof(sys_lan));
	memcpy(sys_lan, lan, 4); 
	sys_lan[3]=0;
	return 0;
}

#define NETWORK_UPDATE_CLEAR_ALL

int DVBNetWorkUpdateProgramStart()
{
#ifdef NETWORK_UPDATE_CLEAR_ALL
 	DVBTSDBClear();
	DVBGroupsClear();
	DVBServicesDBClear();

	DVBSysDBDefaut();
#else
	DVBServicesDBClearNetProg();
#endif

	DVBEPGStop();
	return 0;
}

int DVBNetWorkUpdateProgramStop()
{
	dvb_group_t* pstGroup;
	
	mwDebug("DvbNetWorkUpdateProgramStop entry.\r\n");
	pstGroup = DVBGetCurGroup();
	if(pstGroup == NULL)
	{
		if(DVBGroupGetByID(GROUP_VIDEO)->serviceCount > 0)
		{
			mwDebug("DvbNetWorkUpdateProgramStop set cur group VIDEO\r\n");
			DVBSetCurGroup(DVBGroupGetByID(GROUP_VIDEO));
			DvbSetCurService(&(DVBGroupGetByID(GROUP_VIDEO)->Services[0]));
		}
		else if(DVBGroupGetByID(GROUP_AUDIO)->serviceCount > 0)
		{
			mwDebug("DvbNetWorkUpdateProgramStop set cur group AUDIO\r\n");
			DVBSetCurGroup(DVBGroupGetByID(GROUP_AUDIO));
			DvbSetCurService((&DVBGroupGetByID(GROUP_AUDIO)->Services[0]));
		}
		else
		{
			mwDebug("DvbNetWorkUpdateProgramStop found not program\r\n");
		}
	}
	DvbSiSaveData();
	SaveCurService();
	DVBEPGStart();

	mwDebug("DvbNetWorkUpdateProgramStop return\r\n");

	return 0;
}

static int DVBNetWorkUpdateSort(dvb_service_t* pstServiceList, unsigned int u32Num, unsigned int u32GroupIndex)
{
	int ret = -1;
	unsigned int i;

	mwDebug("DvbNetWorkUpdateSort entry - pstServiceList = %p, u32Num = %d, u32GroupIndex = %d\r\n", pstServiceList, u32Num, u32GroupIndex);
	if(pstServiceList && u32Num)
	{
		switch(u32GroupIndex)
		{
			case DVB_GROUP_TV:
				DVBGroupNetworkSort(DVBGroupGetByID(GROUP_VIDEO), pstServiceList, u32Num);
				break;
			case DVB_GROUP_RADIO:
				DVBGroupNetworkSort(DVBGroupGetByID(GROUP_AUDIO), pstServiceList, u32Num);
				break;
			default:
				
				break;
		}
		ret = 0;
	}
	else
	{
		mwDebug("DvbNetWorkUpdateSort receive error parameter\r\n");
	}
	
	mwDebug("DvbNetWorkUpdateSort return - ret = %d\r\n", ret);

	return ret;
}

//u32GroupIndex: 0-TV, 1-Radio
int DvbNetWorkUpdateProgram(dvb_networt_service_t* pstProgramList, unsigned int u32Num, unsigned int u32GroupIndex, const char* ps8GroupName)
{
	TSDATA* pstTs = NULL;
	dvb_networt_service_t* pstProg;
	unsigned int i;
	dvb_service_t stService;
	dvb_service_t* pstServiceList = NULL;
	unsigned int u32Index = 0;

	mwDebug("DvbNetWorkUpdateProgram entry - pstProgramList = %p, u32Num = %d, u32GroupIndex = %d, ps8GroupName = %s\r\n", pstProgramList, u32Num, u32GroupIndex, ps8GroupName);
	if(!pstProgramList && !u32Num)
	{
		mwDebug("DvbNetWortUpdateProgram entry, error param, pstProgramList = %p, u32Num = %d, u32GroupIndex = %d, ps8GroupName = %s\r\n", pstProgramList, u32Num, u32GroupIndex, ps8GroupName);
		return -1;
	}

	pstServiceList = mwOsAllocMemory(u32Num*sizeof(dvb_service_t));
	if(!pstServiceList)
	{
		mwDebug("DvbNetWortUpdateProgram found malloc failed\r\n");
		return -1;
	}
	
	for(i=0; i<u32Num; i++)
	{
		pstProg = pstProgramList+i;
		pstTs = DVBTSDBFindTSByFrequency(pstProg->freq);
		if(!pstTs)
		{
			pstTs = DVBTSDBCreateTS(pstProg->orgnetid, pstProg->tsid);
			pstTs->tunerParams.bandwidth = 8;
			pstTs->tunerParams.frequency = pstProg->freq;
			pstTs->tunerParams.modulation = pstProg->mod;
			pstTs->tunerParams.symbol_rate = pstProg->sym;
			pstTs->tunerParams.tunertype = pstProg->tunertype;
		}
		else
		{
			pstTs->tunerParams.bandwidth = 8;
			if(pstTs->netId != pstProg->orgnetid || pstTs->tsId != pstProg->tsid)//dvb first
			{
				mwError("DvbNetWorkUpdateProgram found same freq ts id diff[%d], old[%d, %d], new[%d, %d]\r\n", pstTs->tunerParams.frequency, pstTs->netId, pstTs->tsId, pstProg->orgnetid, pstProg->tsid);
				continue;
			}
		}

		stService.frequence = pstProg->freq;
		stService.netId = pstProg->orgnetid;
		stService.serviceId = pstProg->serviceid;
		stService.tsId = pstProg->tsid;

		switch(u32GroupIndex)
		{
			case DVB_GROUP_TV:
				DVBGroupAddItem(DVBGroupGetByID(GROUP_VIDEO), &stService);
				pstServiceList[u32Index] = stService;
				u32Index++;
				break;
			case DVB_GROUP_RADIO:
				DVBGroupAddItem(DVBGroupGetByID(GROUP_AUDIO), &stService);
				pstServiceList[u32Index] = stService;
				u32Index++;
				break;
			default:
				
				break;
		}
		
		if(DVBSevicesDBIsServiceExist(&stService) == 1)
		{
			DVBServicesDBAddItem(&stService);
			DvbServicesDBSetNetName(&stService, pstProg->name, strlen(pstProg->name));
			DvbServicesDBSetNetFlag(&stService, DVB_NETNAME_UTF);
			DVBServicesDBSetLcn(&stService, i+1);
		}										
		mwDebug("DvbNetWorkUpdateProgram, stService[%d, %d, %d, %d], \r\n", stService.frequence, stService.netId, stService.tsId, stService.serviceId);
	}

	DVBNetWorkUpdateSort(pstServiceList, u32Index, u32GroupIndex);
	mwOsFreeMemory(pstServiceList);

	mwDebug("DvbNetWorkUpdateProgram return - ret = 0\r\n");
	return 0;
}

